home *** CD-ROM | disk | FTP | other *** search
/ Chip 2007 January, February, March & April / Chip-Cover-CD-2007-02.iso / Pakiet multimedia / Muzyka / Edytory sampli (probek dzwieku) / ZynAddSubFX_2.2.0 / Setup_ZynAddSubFX-2.2.0.exe / source code / Misc / Master.C < prev    next >
C/C++ Source or Header  |  2005-03-14  |  19KB  |  739 lines

  1. /*
  2.   ZynAddSubFX - a software synthesizer
  3.  
  4.   Master.C - It sends Midi Messages to Parts, receives samples from parts,
  5.              process them with system/insertion effects and mix them
  6.   Copyright (C) 2002-2005 Nasca Octavian Paul
  7.   Author: Nasca Octavian Paul
  8.  
  9.   This program is free software; you can redistribute it and/or modify
  10.   it under the terms of version 2 of the GNU General Public License 
  11.   as published by the Free Software Foundation.
  12.  
  13.   This program is distributed in the hope that it will be useful,
  14.   but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.   GNU General Public License (version 2) for more details.
  17.  
  18.   You should have received a copy of the GNU General Public License (version 2)
  19.   along with this program; if not, write to the Free Software Foundation,
  20.   Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
  21.  
  22. */
  23.  
  24. #include "Master.h"
  25.  
  26. #include <stdio.h>
  27. #include <sys/stat.h>
  28. #include <sys/types.h>
  29.  
  30. #include <unistd.h>
  31.  
  32. Master::Master(){
  33.     swaplr=0;
  34.     
  35.     pthread_mutex_init(&mutex,NULL);
  36.     fft=new FFTwrapper(OSCIL_SIZE);
  37.  
  38.     tmpmixl=new REALTYPE[SOUND_BUFFER_SIZE];
  39.     tmpmixr=new REALTYPE[SOUND_BUFFER_SIZE];
  40.     audiooutl=new REALTYPE[SOUND_BUFFER_SIZE];
  41.     audiooutr=new REALTYPE[SOUND_BUFFER_SIZE];
  42.     
  43.     ksoundbuffersample=-1;//this is only time when this is -1; this means that the GetAudioOutSamples was never called
  44.     ksoundbuffersamplelow=0.0;
  45.     oldsamplel=0.0;oldsampler=0.0;
  46.     shutup=0;
  47.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++) {
  48.     vuoutpeakpart[npart]=1e-9;
  49.     fakepeakpart[npart]=0;
  50.     };
  51.     
  52.     for (int i=0;i<SOUND_BUFFER_SIZE;i++) {
  53.     audiooutl[i]=0.0;
  54.     audiooutr[i]=0.0;
  55.     };
  56.  
  57.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++)
  58.     part[npart]=new Part(µtonal,fft,&mutex);
  59.     
  60.  
  61.  
  62.     //Insertion Effects init        
  63.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++)
  64.         insefx[nefx]=new EffectMgr(1,&mutex);
  65.  
  66.     //System Effects init        
  67.     for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) {
  68.     sysefx[nefx]=new EffectMgr(0,&mutex);
  69.     };
  70.  
  71.     
  72.     defaults();
  73. };
  74.  
  75. void Master::defaults(){
  76.     volume=1.0;
  77.     setPvolume(80);
  78.     setPkeyshift(64);
  79.     
  80.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++){
  81.     part[npart]->defaults();
  82.     part[npart]->Prcvchn=npart%NUM_MIDI_CHANNELS;
  83.     };
  84.  
  85.     partonoff(0,1);//enable the first part
  86.  
  87.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++) {
  88.         insefx[nefx]->defaults();
  89.     Pinsparts[nefx]=-1;
  90.     };
  91.     
  92.     //System Effects init        
  93.     for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) {
  94.     sysefx[nefx]->defaults();
  95.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++){
  96.         if (nefx==0) setPsysefxvol(npart,nefx,64);
  97.         else setPsysefxvol(npart,nefx,0);
  98.     };
  99.     for (int nefxto=0;nefxto<NUM_SYS_EFX;nefxto++)
  100.         setPsysefxsend(nefx,nefxto,0);
  101.     };
  102.  
  103.     sysefx[0]->changeeffect(1);
  104.     microtonal.defaults();
  105.     ShutUp();
  106. };
  107.  
  108. /*
  109.  * Note On Messages (velocity=0 for NoteOff)
  110.  */
  111. void Master::NoteOn(unsigned char chan,unsigned char note,unsigned char velocity){
  112.     dump.dumpnote(chan,note,velocity);
  113.  
  114.     noteon(chan,note,velocity);
  115. };
  116.  
  117. /*
  118.  * Internal Note On (velocity=0 for NoteOff)
  119.  */
  120. void Master::noteon(unsigned char chan,unsigned char note,unsigned char velocity){
  121.     int npart;
  122.     if (velocity!=0){
  123.         for (npart=0;npart<NUM_MIDI_PARTS;npart++){
  124.         if (chan==part[npart]->Prcvchn){
  125.         fakepeakpart[npart]=velocity*2;
  126.         if (part[npart]->Penabled!=0) part[npart]->NoteOn(note,velocity,keyshift);
  127.         };
  128.     };
  129.     }else{
  130.     this->NoteOff(chan,note);
  131.     };
  132.     HDDRecorder.triggernow();    
  133. };
  134.  
  135. /*
  136.  * Note Off Messages
  137.  */
  138. void Master::NoteOff(unsigned char chan,unsigned char note){
  139.     dump.dumpnote(chan,note,0);
  140.     
  141.     noteoff(chan,note);
  142. };
  143.  
  144. /*
  145.  * Internal Note Off
  146.  */
  147. void Master::noteoff(unsigned char chan,unsigned char note){
  148.     int npart;
  149.     for (npart=0;npart<NUM_MIDI_PARTS;npart++){
  150.     if ((chan==part[npart]->Prcvchn) && (part[npart]->Penabled!=0))
  151.         part[npart]->NoteOff(note);    
  152.     };
  153. };
  154.  
  155. /*
  156.  * Controllers 
  157.  */
  158. void Master::SetController(unsigned char chan,unsigned int type,int par){
  159.     dump.dumpcontroller(chan,type,par);
  160.     
  161.     setcontroller(chan,type,par);
  162. };
  163.  
  164. /*
  165.  * Internal Controllers 
  166.  */
  167. void Master::setcontroller(unsigned char chan,unsigned int type,int par){
  168.     if ((type==C_dataentryhi)||(type==C_dataentrylo)||
  169.        (type==C_nrpnhi)||(type==C_nrpnlo)){//Process RPN and NRPN by the Master (ignore the chan)
  170.     ctl.setparameternumber(type,par);
  171.     
  172.     int parhi=-1,parlo=-1,valhi=-1,vallo=-1;
  173.     if (ctl.getnrpn(&parhi,&parlo,&valhi,&vallo)==0){//this is NRPN
  174.         //fprintf(stderr,"rcv. NRPN: %d %d %d %d\n",parhi,parlo,valhi,vallo);
  175.         switch (parhi){
  176.            case 0x04://System Effects
  177.                 if (parlo<NUM_SYS_EFX) {
  178.             sysefx[parlo]->seteffectpar_nolock(valhi,vallo);
  179.             };
  180.                 break;
  181.            case 0x08://Insertion Effects
  182.                 if (parlo<NUM_INS_EFX) {
  183.             insefx[parlo]->seteffectpar_nolock(valhi,vallo);
  184.             };
  185.                 break;
  186.         
  187.         };
  188.     };
  189.     } else {//other controllers
  190.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++){//Send the controller to all part assigned to the channel
  191.         if ((chan==part[npart]->Prcvchn) && (part[npart]->Penabled!=0))
  192.         part[npart]->SetController(type,par);
  193.     };
  194.     };
  195. };
  196.  
  197.  
  198. /*
  199.  * Enable/Disable a part
  200.  */
  201. void Master::partonoff(int npart,int what){
  202.     if (npart>=NUM_MIDI_PARTS) return;
  203.     if (what==0){//disable part
  204.     fakepeakpart[npart]=0;
  205.     part[npart]->Penabled=0;
  206.     part[npart]->cleanup();
  207.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++){
  208.         if (Pinsparts[nefx]==npart) {
  209.         insefx[nefx]->cleanup();
  210.     };
  211.     };
  212.     } else {//enabled
  213.     part[npart]->Penabled=1;
  214.     fakepeakpart[npart]=0;
  215.     };
  216. };
  217.  
  218. /*
  219.  * Master audio out (the final sound)
  220.  */
  221. void Master::AudioOut(REALTYPE *outl,REALTYPE *outr){
  222.     int i,npart,nefx;
  223.  
  224. /*    //test!!!!!!!!!!!!! se poate bloca aici (mutex)
  225.     if (seq.play){
  226.     int type,par1,par2,again,midichan;
  227.     int ntrack=1;
  228. //        do{
  229.         again=seq.getevent(ntrack,&midichan,&type,&par1,&par2);
  230.         if (type>0) {
  231. //        printf("aaa\n");    
  232.     
  233.                 if (type==1){//note_on or note_off
  234.             if (par2!=0) NoteOn(midichan,par1,par2);
  235.                 else NoteOff(midichan,par1);
  236.                 };
  237.         };
  238. //        } while (again);
  239.     };
  240. */
  241.  
  242.  
  243. //    printf("zzzz\n");
  244.  
  245.  
  246.     //Swaps the Left channel with Right Channel (if it is asked for)
  247.     if (swaplr!=0){
  248.         REALTYPE *tmp=outl;
  249.     outl=outr;
  250.     outr=tmp;
  251.     };
  252.     
  253.     //clean up the output samples 
  254.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  255.     outl[i]=0.0;
  256.     outr[i]=0.0;
  257.     };
  258.  
  259.     //Compute part samples and store them part[npart]->partoutl,partoutr
  260.     for (npart=0;npart<NUM_MIDI_PARTS;npart++)
  261.     if (part[npart]->Penabled!=0) part[npart]->ComputePartSmps();
  262.  
  263.     //Insertion effects 
  264.     for (nefx=0;nefx<NUM_INS_EFX;nefx++){
  265.     if (Pinsparts[nefx]>=0) {
  266.         int efxpart=Pinsparts[nefx];
  267.         if (part[efxpart]->Penabled!=0) 
  268.         insefx[nefx]->out(part[efxpart]->partoutl,part[efxpart]->partoutr);
  269.     };
  270.     };
  271.     
  272.     
  273.     //Apply the part volumes and pannings (after insertion effects)
  274.     for (npart=0;npart<NUM_MIDI_PARTS;npart++){
  275.     if (part[npart]->Penabled==0)  continue; 
  276.  
  277.     REALTYPE newvol_l=part[npart]->volume;
  278.     REALTYPE newvol_r=part[npart]->volume;
  279.     REALTYPE oldvol_l=part[npart]->oldvolumel;
  280.     REALTYPE oldvol_r=part[npart]->oldvolumer;
  281.     REALTYPE pan=part[npart]->panning;
  282.     if (pan<0.5) newvol_l*=pan*2.0;
  283.            else newvol_r*=(1.0-pan)*2.0;
  284.     
  285.     if (ABOVE_AMPLITUDE_THRESHOLD(oldvol_l,newvol_l)||
  286.         ABOVE_AMPLITUDE_THRESHOLD(oldvol_r,newvol_r)){//the volume or the panning has changed and needs interpolation
  287.         
  288.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  289.         REALTYPE vol_l=INTERPOLATE_AMPLITUDE(oldvol_l,newvol_l,i,SOUND_BUFFER_SIZE);
  290.         REALTYPE vol_r=INTERPOLATE_AMPLITUDE(oldvol_r,newvol_r,i,SOUND_BUFFER_SIZE);
  291.         part[npart]->partoutl[i]*=vol_l;
  292.             part[npart]->partoutr[i]*=vol_r;
  293.         };
  294.         part[npart]->oldvolumel=newvol_l;
  295.         part[npart]->oldvolumer=newvol_r;
  296.  
  297.     } else {
  298.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {//the volume did not changed
  299.         part[npart]->partoutl[i]*=newvol_l;
  300.             part[npart]->partoutr[i]*=newvol_r;
  301.         };
  302.     };
  303.     };
  304.  
  305.  
  306.     //System effects
  307.     for (nefx=0;nefx<NUM_SYS_EFX;nefx++){
  308.     if (sysefx[nefx]->geteffect()==0) continue;//the effect is disabled
  309.  
  310.         //Clean up the samples used by the system effects
  311.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  312.         tmpmixl[i]=0.0;
  313.         tmpmixr[i]=0.0;
  314.     };
  315.  
  316.     //Mix the channels according to the part settings about System Effect
  317.     for (npart=0;npart<NUM_MIDI_PARTS;npart++){
  318.         //skip if the part has no output to effect        
  319.         if (Psysefxvol[nefx][npart]==0) continue;
  320.  
  321.         //skip if the part is disabled
  322.         if (part[npart]->Penabled==0) continue;
  323.  
  324.         //the output volume of each part to system effect
  325.         REALTYPE vol=sysefxvol[nefx][npart];
  326.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  327.         tmpmixl[i]+=part[npart]->partoutl[i]*vol;
  328.         tmpmixr[i]+=part[npart]->partoutr[i]*vol;
  329.         };
  330.     };
  331.     
  332.     // system effect send to next ones
  333.     for (int nefxfrom=0;nefxfrom<nefx;nefxfrom++){
  334.         if (Psysefxsend[nefxfrom][nefx]!=0){
  335.         REALTYPE v=sysefxsend[nefxfrom][nefx];
  336.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  337.             tmpmixl[i]+=sysefx[nefxfrom]->efxoutl[i]*v;
  338.             tmpmixr[i]+=sysefx[nefxfrom]->efxoutr[i]*v;
  339.         };
  340.         };
  341.     };
  342.  
  343.     sysefx[nefx]->out(tmpmixl,tmpmixr);
  344.     
  345.     //Add the System Effect to sound output
  346.     REALTYPE outvol=sysefx[nefx]->sysefxgetvolume();
  347.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  348.         outl[i]+=tmpmixl[i]*outvol;
  349.         outr[i]+=tmpmixr[i]*outvol;
  350.     };
  351.  
  352.     };
  353.  
  354.     //Mix all parts
  355.     for (npart=0;npart<NUM_MIDI_PARTS;npart++){
  356.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {//the volume did not changed
  357.             outl[i]+=part[npart]->partoutl[i];
  358.         outr[i]+=part[npart]->partoutr[i];
  359.     };
  360.     };
  361.     
  362.     //Insertion effects for Master Out
  363.     for (nefx=0;nefx<NUM_INS_EFX;nefx++){
  364.     if (Pinsparts[nefx] == -2) 
  365.         insefx[nefx]->out(outl,outr);
  366.     };
  367.  
  368.     //Master Volume
  369.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  370.         outl[i]*=volume;
  371.         outr[i]*=volume;
  372.     };
  373.  
  374.     //Peak computation (for vumeters)
  375.     vuoutpeakl=1e-12;vuoutpeakr=1e-12;
  376.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  377.         if (fabs(outl[i])>vuoutpeakl) vuoutpeakl=fabs(outl[i]);
  378.         if (fabs(outr[i])>vuoutpeakr) vuoutpeakr=fabs(outr[i]);
  379.     };
  380.     if ((vuoutpeakl>1.0)||(vuoutpeakr>1.0)) vuclipped=1;
  381.     if (vumaxoutpeakl<vuoutpeakl) vumaxoutpeakl=vuoutpeakl;
  382.     if (vumaxoutpeakr<vuoutpeakr) vumaxoutpeakr=vuoutpeakr;
  383.  
  384.     //RMS Peak computation (for vumeters)
  385.     vurmspeakl=1e-12;vurmspeakr=1e-12;
  386.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  387.         vurmspeakl+=outl[i]*outl[i];
  388.         vurmspeakr+=outr[i]*outr[i];
  389.     };
  390.     vurmspeakl=sqrt(vurmspeakl/SOUND_BUFFER_SIZE);
  391.     vurmspeakr=sqrt(vurmspeakr/SOUND_BUFFER_SIZE);
  392.     
  393.     //Part Peak computation (for Part vumeters or fake part vumeters)
  394.     for (npart=0;npart<NUM_MIDI_PARTS;npart++){
  395.     vuoutpeakpart[npart]=1.0e-12;
  396.     if (part[npart]->Penabled!=0) {
  397.             REALTYPE *outl=part[npart]->partoutl,
  398.              *outr=part[npart]->partoutr;
  399.         for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  400.         REALTYPE tmp=fabs(outl[i]+outr[i]);
  401.             if (tmp>vuoutpeakpart[npart]) vuoutpeakpart[npart]=tmp;
  402.         };
  403.         vuoutpeakpart[npart]*=volume;
  404.     } else {
  405.         if (fakepeakpart[npart]>1) fakepeakpart[npart]--;
  406.     };
  407.     };
  408.  
  409.  
  410.     //Shutup if it is asked (with fade-out)
  411.     if (shutup!=0){
  412.     for (i=0;i<SOUND_BUFFER_SIZE;i++) {
  413.         REALTYPE tmp=(SOUND_BUFFER_SIZE-i)/(REALTYPE) SOUND_BUFFER_SIZE;
  414.         outl[i]*=tmp;
  415.         outr[i]*=tmp;
  416.     };
  417.     ShutUp();
  418.     };
  419.  
  420.     //update the LFO's time
  421.     LFOParams::time++;
  422.  
  423.     if (HDDRecorder.recording()) HDDRecorder.recordbuffer(outl,outr);
  424.     dump.inctick();
  425. };
  426.  
  427. void Master::GetAudioOutSamples(int nsamples,int samplerate,REALTYPE *outl,REALTYPE *outr){
  428.     if (ksoundbuffersample==-1){//first time
  429.         AudioOut(&audiooutl[0],&audiooutr[0]);
  430.             ksoundbuffersample=0;
  431.     };
  432.  
  433.  
  434.     if (samplerate==SAMPLE_RATE){//no resample
  435.     int ksample=0;
  436.         while (ksample<nsamples){
  437.         outl[ksample]=audiooutl[ksoundbuffersample];
  438.         outr[ksample]=audiooutr[ksoundbuffersample];
  439.  
  440.         ksample++;
  441.         ksoundbuffersample++;
  442.         if (ksoundbuffersample>=SOUND_BUFFER_SIZE){
  443.         AudioOut(&audiooutl[0],&audiooutr[0]);
  444.             ksoundbuffersample=0;
  445.         };
  446.     };
  447.     } else {//Resample
  448.     int ksample=0;
  449.     REALTYPE srinc=SAMPLE_RATE/(REALTYPE)samplerate;
  450.  
  451.         while (ksample<nsamples){
  452.         if (ksoundbuffersample!=0){
  453.         outl[ksample]=audiooutl[ksoundbuffersample]*ksoundbuffersamplelow
  454.             +audiooutl[ksoundbuffersample-1]*(1.0-ksoundbuffersamplelow);
  455.         outr[ksample]=audiooutr[ksoundbuffersample]*ksoundbuffersamplelow
  456.             +audiooutr[ksoundbuffersample-1]*(1.0-ksoundbuffersamplelow);
  457.         } else {
  458.         outl[ksample]=audiooutl[ksoundbuffersample]*ksoundbuffersamplelow
  459.             +oldsamplel*(1.0-ksoundbuffersamplelow);
  460.         outr[ksample]=audiooutr[ksoundbuffersample]*ksoundbuffersamplelow
  461.             +oldsampler*(1.0-ksoundbuffersamplelow);
  462.         };
  463.         
  464.         ksample++;
  465.         
  466.         ksoundbuffersamplelow+=srinc;
  467.         if (ksoundbuffersamplelow>=1.0){
  468.         ksoundbuffersample+=(int) floor(ksoundbuffersamplelow);
  469.         ksoundbuffersamplelow=ksoundbuffersamplelow-floor(ksoundbuffersamplelow);
  470.         };
  471.         
  472.         if (ksoundbuffersample>=SOUND_BUFFER_SIZE){
  473.         oldsamplel=audiooutl[SOUND_BUFFER_SIZE-1];
  474.         oldsampler=audiooutr[SOUND_BUFFER_SIZE-1];
  475.         AudioOut(&audiooutl[0],&audiooutr[0]);
  476.             ksoundbuffersample=0;
  477.         };
  478.     };
  479.     };
  480. };
  481.  
  482.  
  483. Master::~Master(){
  484.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++) delete (part[npart]);
  485.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++) delete (insefx[nefx]);
  486.     for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) delete (sysefx[nefx]);
  487.     
  488.     delete [] audiooutl;
  489.     delete [] audiooutr;
  490.     delete [] tmpmixl;
  491.     delete [] tmpmixr;
  492.     delete (fft);
  493.  
  494.     pthread_mutex_destroy(&mutex);
  495. };
  496.  
  497.  
  498. /*
  499.  * Parameter control
  500.  */
  501. void Master::setPvolume(char Pvolume_){
  502.     Pvolume=Pvolume_;
  503.     volume=dB2rap((Pvolume-96.0)/96.0*40.0);
  504. };
  505.  
  506. void Master::setPkeyshift(char Pkeyshift_){
  507.     Pkeyshift=Pkeyshift_;
  508.     keyshift=(int)Pkeyshift-64;
  509. };
  510.  
  511.  
  512. void Master::setPsysefxvol(int Ppart,int Pefx,char Pvol){
  513.     Psysefxvol[Pefx][Ppart]=Pvol;
  514.     sysefxvol[Pefx][Ppart]=pow(0.1,(1.0-Pvol/96.0)*2.0);
  515. };
  516.  
  517. void Master::setPsysefxsend(int Pefxfrom,int Pefxto,char Pvol){
  518.     Psysefxsend[Pefxfrom][Pefxto]=Pvol;
  519.     sysefxsend[Pefxfrom][Pefxto]=pow(0.1,(1.0-Pvol/96.0)*2.0);
  520. };
  521.  
  522.  
  523. /*
  524.  * Panic! (Clean up all parts and effects)
  525.  */
  526. void Master::ShutUp(){
  527.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++) {
  528.     part[npart]->cleanup();
  529.     fakepeakpart[npart]=0;    
  530.     };
  531.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++) insefx[nefx]->cleanup();
  532.     for (int nefx=0;nefx<NUM_SYS_EFX;nefx++) sysefx[nefx]->cleanup();
  533.     vuresetpeaks();
  534.     shutup=0;
  535. };
  536.  
  537.  
  538. /*
  539.  * Reset peaks and clear the "cliped" flag (for VU-meter)
  540.  */
  541. void Master::vuresetpeaks(){
  542.     vuoutpeakl=1e-9;vuoutpeakr=1e-9;vumaxoutpeakl=1e-9;vumaxoutpeakr=1e-9;
  543.     vuclipped=0;
  544. };
  545.  
  546.  
  547.  
  548. void Master::applyparameters(){
  549.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++){
  550.     part[npart]->applyparameters();
  551.     };
  552. };
  553.  
  554. void Master::add2XML(XMLwrapper *xml){
  555.     xml->addpar("volume",Pvolume);
  556.     xml->addpar("key_shift",Pkeyshift);
  557.     xml->addparbool("nrpn_receive",ctl.NRPN.receive);
  558.  
  559.     xml->beginbranch("MICROTONAL");
  560.     microtonal.add2XML(xml);
  561.     xml->endbranch();
  562.  
  563.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++){
  564.     xml->beginbranch("PART",npart);
  565.     part[npart]->add2XML(xml);
  566.     xml->endbranch();
  567.     };
  568.     
  569.     xml->beginbranch("SYSTEM_EFFECTS");
  570.     for (int nefx=0;nefx<NUM_SYS_EFX;nefx++){
  571.         xml->beginbranch("SYSTEM_EFFECT",nefx);
  572.         xml->beginbranch("EFFECT");
  573.             sysefx[nefx]->add2XML(xml);
  574.         xml->endbranch();
  575.  
  576.         for (int pefx=0;pefx<NUM_MIDI_PARTS;pefx++){
  577.             xml->beginbranch("VOLUME",pefx);
  578.             xml->addpar("vol",Psysefxvol[nefx][pefx]);
  579.             xml->endbranch();    
  580.         };
  581.  
  582.         for (int tonefx=nefx+1;tonefx<NUM_SYS_EFX;tonefx++){
  583.             xml->beginbranch("SENDTO",tonefx);
  584.             xml->addpar("send_vol",Psysefxsend[nefx][tonefx]);
  585.             xml->endbranch();    
  586.         };
  587.         
  588.         
  589.         xml->endbranch();
  590.     };
  591.     xml->endbranch();
  592.  
  593.     xml->beginbranch("INSERTION_EFFECTS");
  594.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++){
  595.         xml->beginbranch("INSERTION_EFFECT",nefx);
  596.         xml->addpar("part",Pinsparts[nefx]);
  597.  
  598.         xml->beginbranch("EFFECT");
  599.             insefx[nefx]->add2XML(xml);
  600.         xml->endbranch();
  601.         xml->endbranch();
  602.     };
  603.     
  604.     xml->endbranch();
  605.     
  606. };
  607.  
  608.  
  609. int Master::getalldata(char **data){
  610.     XMLwrapper *xml=new XMLwrapper();
  611.  
  612.     xml->beginbranch("MASTER");
  613.  
  614.     pthread_mutex_lock(&mutex);
  615.     add2XML(xml);
  616.     pthread_mutex_unlock(&mutex);
  617.  
  618.     xml->endbranch();
  619.  
  620.     *data=xml->getXMLdata();
  621.     delete (xml);
  622.     return(strlen(*data)+1);
  623. };
  624.  
  625. void Master::putalldata(char *data,int size){
  626.     XMLwrapper *xml=new XMLwrapper();
  627.     if (!xml->putXMLdata(data)) {
  628.     delete(xml);
  629.     return;
  630.     };
  631.     
  632.     if (xml->enterbranch("MASTER")==0) return;
  633.  
  634.     pthread_mutex_lock(&mutex);
  635.     getfromXML(xml);
  636.     pthread_mutex_unlock(&mutex);
  637.  
  638.     xml->exitbranch();
  639.     
  640.     delete(xml);
  641. };
  642.  
  643. int Master::saveXML(char *filename){
  644.     XMLwrapper *xml=new XMLwrapper();
  645.  
  646.     xml->beginbranch("MASTER");
  647.     add2XML(xml);
  648.     xml->endbranch();
  649.  
  650.     int result=xml->saveXMLfile(filename);
  651.     delete (xml);
  652.     return(result);
  653. };
  654.  
  655.  
  656.  
  657. int Master::loadXML(char *filename){
  658.     XMLwrapper *xml=new XMLwrapper();
  659.     if (xml->loadXMLfile(filename)<0) {
  660.     delete(xml);
  661.     return(-1);
  662.     };
  663.     
  664.     if (xml->enterbranch("MASTER")==0) return(-10);
  665.     getfromXML(xml);
  666.     xml->exitbranch();
  667.     
  668.     delete(xml);
  669.     return(0);
  670. };
  671.  
  672. void Master::getfromXML(XMLwrapper *xml){
  673.     setPvolume(xml->getpar127("volume",Pvolume));
  674.     setPkeyshift(xml->getpar127("key_shift",Pkeyshift));
  675.     ctl.NRPN.receive=xml->getparbool("nrpn_receive",ctl.NRPN.receive);
  676.     
  677.     
  678.     part[0]->Penabled=0;
  679.     for (int npart=0;npart<NUM_MIDI_PARTS;npart++){
  680.     if (xml->enterbranch("PART",npart)==0) continue;
  681.         part[npart]->getfromXML(xml);
  682.     xml->exitbranch();
  683.     };
  684.  
  685.     if (xml->enterbranch("MICROTONAL")){
  686.         microtonal.getfromXML(xml);
  687.         xml->exitbranch();
  688.     };
  689.     
  690.     sysefx[0]->changeeffect(0);
  691.     if (xml->enterbranch("SYSTEM_EFFECTS")){
  692.     for (int nefx=0;nefx<NUM_SYS_EFX;nefx++){
  693.         if (xml->enterbranch("SYSTEM_EFFECT",nefx)==0) continue;
  694.         if (xml->enterbranch("EFFECT")){
  695.             sysefx[nefx]->getfromXML(xml);
  696.             xml->exitbranch();
  697.         };
  698.  
  699.         for (int partefx=0;partefx<NUM_MIDI_PARTS;partefx++){
  700.             if (xml->enterbranch("VOLUME",partefx)==0) continue;
  701.             setPsysefxvol(partefx,nefx,xml->getpar127("vol",Psysefxvol[partefx][nefx]));
  702.             xml->exitbranch();    
  703.         };
  704.  
  705.         for (int tonefx=nefx+1;tonefx<NUM_SYS_EFX;tonefx++){
  706.             if (xml->enterbranch("SENDTO",tonefx)==0) continue;
  707.             setPsysefxsend(nefx,tonefx,xml->getpar127("send_vol",Psysefxsend[nefx][tonefx]));
  708.             xml->exitbranch();    
  709.         };
  710.         xml->exitbranch();
  711.     };
  712.     xml->exitbranch();
  713.     };
  714.  
  715.  
  716.     if (xml->enterbranch("INSERTION_EFFECTS")){
  717.     for (int nefx=0;nefx<NUM_INS_EFX;nefx++){
  718.     
  719.         if (xml->enterbranch("INSERTION_EFFECT",nefx)==0) continue;
  720.         Pinsparts[nefx]=xml->getpar("part",Pinsparts[nefx],-1,NUM_MIDI_PARTS);
  721.  
  722.         if (xml->enterbranch("EFFECT")){
  723.             insefx[nefx]->getfromXML(xml);
  724.             xml->exitbranch();
  725.         };
  726.         xml->exitbranch();
  727.  
  728.     };
  729.     
  730.     xml->exitbranch();
  731.     };
  732.     
  733.     
  734. };
  735.  
  736.  
  737.  
  738.  
  739.